package cn.lutu.lutu.controller;

import cn.lutu.lutu.mapper.UserMapper;
import cn.lutu.lutu.pojo.dto.UserChangePasswordDTO;
import cn.lutu.lutu.pojo.dto.UserLoginDTO;
import cn.lutu.lutu.pojo.dto.UserRegDTO;
import cn.lutu.lutu.pojo.dto.UserUpdateDTO;
import cn.lutu.lutu.pojo.entity.User;
import cn.lutu.lutu.pojo.vo.UserVO;
import cn.lutu.lutu.response.ResultVO;
import cn.lutu.lutu.response.StatusCode;
import cn.lutu.lutu.security.CustomUserDetails;
import cn.lutu.lutu.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
/**
 * @date 2023/6/5
 * @author songjie
 */
@RestController
@Api(tags = "01.用户模块")
@RequestMapping("/v1/users")
@Slf4j
public class UserController {
    @Autowired
    UserMapper userMapper;
    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    UserService userService;
    /**
     * 注册
     * */
    @PostMapping("reg")
    @ApiOperation(value = "注册功能")
    public ResultVO reg(@RequestBody UserRegDTO userRegDTO){
        log.info("判断用户名是否存在");
       if(userService.selectByEmail(userRegDTO.getEmail())){
           return new ResultVO(StatusCode.EMAIL_ALREADY_EXSTS);
       }
       /*log.info("判断邮箱格式是否正确");
       if(!userService.matchEmail(userRegDTO.getEmail())){
           return new ResultVO(StatusCode.EMAIL_ERROR);
       }*/
       log.info("进入注册请求");
       userService.addNew(userRegDTO);
        return ResultVO.ok();
    }
    @Autowired
    AuthenticationManager authenticationManager;
    /**登录*/
    @PostMapping("login")
    @ApiOperation(value = "登录功能")
    private ResultVO login(@RequestBody UserLoginDTO userLoginDTO){
        log.info("通过认证管理器启动Security的认证流程  返回认证结果对象");
        Authentication result = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
                userLoginDTO.getUserName(), userLoginDTO.getPassword()));
        log.info("将认证结果保存到Security上下文中   让Security框架记住登录状态");
        SecurityContextHolder.getContext().setAuthentication(result);
        log.info("进入登录请求");
        return ResultVO.ok(result.getPrincipal());
    }
    /**退出登录*/
    @PostMapping("logout")
    @ApiOperation(value = "退出登录")
    public void logout(){
        log.info("从Security框架中删除认证数据");
        SecurityContextHolder.clearContext();
    }
    @PostMapping("update")
    @ApiOperation(value = "修改用户信息")
    public ResultVO update(@RequestBody UserUpdateDTO userUpdateDTO){
        log.info("开始处理修改用户信息请求");
        if(!userService.matchEmail(userUpdateDTO.getEmail())){
            return new ResultVO(StatusCode.EMAIL_ERROR);
        }
        userService.updateNew(userUpdateDTO);
        return ResultVO.ok();
    }
    @GetMapping("details")
    @ApiOperation(value = "查询用户信息")
    private ResultVO select(@AuthenticationPrincipal CustomUserDetails cud){
        log.info("处理查询用户信息");
        List<UserVO> list =userMapper.selectById(cud.getId());
        return new ResultVO(StatusCode.SUCCESS,list);
    }

    @PostMapping("retrievePassword")
    @ApiOperation(value="找回密码")
    public ResultVO retrievePassword(@RequestBody UserChangePasswordDTO userChangePasswordDTO){
        User user= userService.retrievePasswordUser(userChangePasswordDTO);
        userMapper.update(user);
        return ResultVO.ok();
    }
    @PostMapping("changePassword")
    @ApiOperation(value="修改密码")
    public void changePassword(@AuthenticationPrincipal CustomUserDetails cud,String password){
        userService.changePasswordUser(cud,password);
    }

}
